Страницы и версии строк

Структура страниц

Размер страницы данных в PostgreSQL обычно составляет 8 KB (8192 байта)
Pasted image 20240922153513.png

  • Заголовок страницы — 24 байта. Общая инфа

  • Массив указателей строк. Это массив указателей на отдельные строки (tuples) на странице. Каждый указатель (line pointer) занимает 4 байта и содержит:

    • смещение версии строки относительно начала страницы (15 бит);
    • статус версии строки (2 бита);
    • длину версии строки (15 бит).
  • Свободное пространство. Сюда растут строки и указатели

  • Данные строк. Включая заголовки строк (tuple headers) и сами данные.

  • Специальная область. Используется некоторыми типами индексов для хранения вспомогательной информации.
    Чтобы увидеть заголовок страницы:

SELECT * FROM page_header(get_raw_page('pg_class', 0));

Указатели

Ссылки внутри например деревьев индексом указывают не на сами данные а на указатели. Так как это удобнее, можно обращаться просто по номеру тк размеры одинаковые. А сами указатели уже указывают на данные.
Также такая схема удобна тем, что при изменении версии строки достаточно изменить указатель и не менять все деревья.

Структура версий строк

  • xmin, xmax — номера транзакций, которые отличают данную версию от других версий той же строки;
  • infomask — ряд информационных битов, определяющих свойства версии;
  • ctid — ссылка на следующую, более новую версию той же строки;
  • битовая карта неопределенных значений — массив битов, отмечающих столбцы, которые допускают неопределенные значения (NULL).

Также, стоит заметить, что значения в странице хранятся также как они бы хранились в оперативной памяти. А значит с отступами в одно машинное слово. А значит, таблица с типами полей итн булл инт булл будет весить больше чем инт инт булл булл.

Еще одна возможная микрооптимизация — перенести в начало таблицы все столбцы фиксированного размера, не допускающие неопределенных значений. Доступ к таким полям будет более эффективным благодаря возможности закешировать смещение поля от начала версии строки.

Выполнение операций над версиями строк

Чтобы разные версии одной и той же строки можно было различить, каждая из версий имеет две отметки, определяющие ее «время действия», — xmin и xmax. Но используется не время как таковое, а постоянно увеличивающийся счетчик номеров транзакций.

  • Когда строка создается, значение xmin устанавливается равным номеру транзакции, выполнившей команду INSERT.
  • Когда строка удаляется, значению xmax текущей версии присваивается номер транзакции, выполнившей команду DELETE.
  • Команда UPDATE распределяется на DELETE и INSERT.

Во время выполнения изменений поля, создаетя новая версия поля и выставляются флаги, что транзакция закоммичена или нет, а также выставляется номер отменяющей транзации в старой версии строки.

Продолжение следует...
https://habr.com/ru/articles/830924/